package com.yonyou.pmclouds.basecom.bp.processor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yonyou.pmclouds.basecom.conf.NCInvokerConfiguration;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst4NCC;
import com.yonyou.pmclouds.basecom.entity.SuperVO;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.basecom.util.BeanHelper;
import com.yonyou.pmclouds.basecom.util.CommonFieldConst;
import com.yonyou.pmclouds.outter.user.UserInfoServerQuery;
import com.yonyou.pmclouds.picture.entity.PictureVO;
import com.yonyou.pmclouds.picture.rmiitf.PictureRemoteService;
import com.yonyou.pmclouds.project.entity.ProjectVO;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.user.entity.UserInfo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * 友工程单据集成文档中心
 *
 * @zhangwce
 */
@Component
@Slf4j
public class DocCenterProcessor<T extends SuperVO> implements SingleProcessor<T> {

    public static final String NC_PROJECT_METADATA = "69673c89-bcd2-44d0-aeb0-2ad08882b016";
    public static final String DOCBIZ_SERVICE_NAME = "DocBizAddImplServlet";
    public static final String DOCBIZ_SERVICE_SERVLET_PATH = "/service/DocBizAddImplServlet";
    public static final String NC_UBL_SERVICE = "nc.bs.pmcloud.servlet.ublimpl.DocBIzAddImp4UBL";

    @Autowired
    private NCInvokerConfiguration.Invoker invoker;
    @Autowired
    private ProjectSimpleQuery query;
    @Autowired
    private UserInfoServerQuery userInfoServerQuery;
    @Autowired
    private PictureRemoteService pictureRemoteService;


    private ObjectMapper mapper = new ObjectMapper();

    private Map<String,String> billTypeNccMap = new HashMap<>();

    public DocCenterProcessor(){
        init();
    }

    private void init(){
        billTypeNccMap = BillTypeConst4NCC.getPMCToNCCMap();
    }

    @Override
    public void process(T vo, T orig) throws BusinessException {

        String pkProject = BeanHelper.getProperty(vo, CommonFieldConst.PK_PROJECT) == null ? (String)BeanHelper.getProperty(vo,CommonFieldConst.PKPROJECT) :
                (String)BeanHelper.getProperty(vo,CommonFieldConst.PK_PROJECT);

        if(StringUtils.isEmpty(pkProject))
            return;
        ProjectVO projectVO = query.queryProject(pkProject);
        if(projectVO == null || StringUtils.isEmpty(projectVO.getSrcType()) || StringUtils.isEmpty(projectVO.getPkSrc()))
            return;

        Map<String, Object> requestParams = getDocParamVO(vo,projectVO.getPkSrc(),projectVO.getPkOrg());

        Future<NCInvokerConfiguration.Result> resultFuture = invoker.invokeAsync(DOCBIZ_SERVICE_NAME,
                DOCBIZ_SERVICE_SERVLET_PATH, requestParams, RuntimeEnvironment.getTenantId(),
                RuntimeEnvironment.getLoginUserId(), null);

        try {
            NCInvokerConfiguration.Result invokeResult = resultFuture.get(10, TimeUnit.SECONDS);

            dealResult(invokeResult);

        } catch (Exception e) {
            log.error("解析NC服务结果异常:"+e.getMessage());
            throw  new BusinessException(e);
        }

    }

    /**
     * 处理返回结果
     *
     * @param invokeResult
     */
    private void dealResult(NCInvokerConfiguration.Result invokeResult) {
        if (invokeResult == null || invokeResult.getResult() == null) {
            log.error("请求NC服务异常, 返回结果: {}", invokeResult == null ? null : invokeResult.getResult());
        }

        if (!NCInvokerConfiguration.Result.STATUS_OK.equals(invokeResult.getStatus())) {
            log.error("请求NC服务异常, 返回状态: {}, 返回结果: {}", invokeResult.getStatus(), invokeResult.getResult());
        }

        Map resultMap = new HashMap();
        try {
            resultMap = mapper.readValue(invokeResult.getResult(), Map.class);
        } catch (IOException e) {
            log.error(e.getMessage(),e);
        }
        if (!"ok".equals(resultMap.get("resultCode"))) {
            log.error("请求NC服务异常，返回result：{}", invokeResult.getResult());
        }
    }

    /**
     * 构建文档中心所需参数
     *
     * @param vo
     * @return
     * @throws BusinessException
     */
    private Map<String, Object> getDocParamVO(T vo,String pkSrcProject,String pkOrg) throws BusinessException {
        DocCenterParamVO paramVO = getDocBizParamVO(vo,pkOrg);

        Map<String,Object> requestParams = new HashMap<>();
        requestParams.put("bizVO",paramVO);
        requestParams.put("archiveMap",getArchMetaMap(vo,pkSrcProject));
        return requestParams;
    }

    /**
     * 构建文档中心所需的业务纬度信息 这里目前只有项目
     *
     * @param vo
     * @param pkSrcProject
     * @return
     */
    private Map<String,String> getArchMetaMap(SuperVO vo,String pkSrcProject) {
        Map<String,String> metaValueMap = new HashMap<>();
        if(StringUtils.isEmpty(pkSrcProject))
            return metaValueMap;

        metaValueMap.put(NC_PROJECT_METADATA,pkSrcProject);

        return metaValueMap;
    }

    /**
     * 生辰文档中心业务信息
     *
     * @param vo
     * @return
     */
    private DocCenterParamVO getDocBizParamVO(SuperVO vo,String pkorg) throws BusinessException {
        DocCenterParamVO paramVO = new DocCenterParamVO();
        paramVO.setPkBill(BeanHelper.getId(vo));
        paramVO.setPkOrg(pkorg);
        String billtype = BeanHelper.getProperty(vo, CommonFieldConst.BILL_TYPE) == null ? (String)BeanHelper.getProperty(vo,CommonFieldConst.BILLTYPE) :
                (String)BeanHelper.getProperty(vo,CommonFieldConst.BILL_TYPE);

        paramVO.setBillType(billTypeNccMap.get(billtype));

        Date creationtime = BeanHelper.getProperty(vo,CommonFieldConst.CREATIONTIME) == null ?null:(Date)BeanHelper.getProperty(vo,CommonFieldConst.CREATIONTIME) ;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = simpleDateFormat.format(creationtime);
        paramVO.setBillmaketime(dateStr);

        UserInfo userinfo = userInfoServerQuery.queryUser(String.valueOf(BeanHelper.getProperty(vo,CommonFieldConst.CREATOR)) );
        if(userinfo != null)
            paramVO.setUserMobile(userinfo.getUserMobile());

        String pkBill = BeanHelper.getId(vo);
        Map<String, List<PictureVO>> picMap = pictureRemoteService.getPicsByPkBill(new String[]{pkBill});
        if(picMap != null || picMap.size() > 0){
            List<PictureVO> list =  picMap.get(pkBill);
            if(list != null && list.size()>0){
                paramVO.setFilenum(list.size());
            }
        }


        return paramVO;
    }
}

@Data
class DocCenterParamVO implements Serializable {

    private String pkBill;
    private String pkOrg;
    private String billType;
    private String billcode;
    private String userMobile;
    private String billmaketime;
    private Integer filenum;

}
